package com.hzhc.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzhc.entity.SysDict;
import com.hzhc.entity.SysDictType;
import com.hzhc.enumBean.ResultUtilCodeEnum;
import com.hzhc.enumBean.TimeDiff;
import com.hzhc.mapper.SysDictMapper;
import com.hzhc.mapper.SysDictTypeMapper;
import com.hzhc.service.SysDictService;
import com.hzhc.utils.ResultUtil;
import com.hzhc.vo.SysDictVo;
import com.hzhc.vo.SystemInfoVo;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;

import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.List;

/**
 * <p>
 * 基础字典 服务实现类
 * </p>
 *
 * @author 功不唐捐
 * @since 2024-04-07
 */
@Service
@RequiredArgsConstructor
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {

    private final SysDictTypeMapper sysDictTypeMapper;

    @Override
    public List<SysDictVo> getSysDictList(Page<SysDictVo> pagination, SysDictVo sysDictVo) {
        List<SysDictType> sysDictTypes = sysDictTypeMapper.selectList(new QueryWrapper<SysDictType>()
                .eq("code", sysDictVo.getSysDictTypeCode()).eq("disable", 0));
        if (!sysDictTypes.isEmpty()) {
            sysDictVo.setTypeId(sysDictTypes.get(0).getId());
        }
        IPage<SysDictVo> sysDictList = baseMapper.getSysDictList(pagination, sysDictVo);
        return sysDictList.getRecords();
    }

    @Override
    public boolean addDict(SysDict sysDict) {
        sysDict.setCreateTime(LocalDateTime.now());
        return save(sysDict);
    }

    @Override
    public boolean updateDict(SysDict sysDict) {
        sysDict.setUpdateTime(LocalDateTime.now());
        boolean b = updateById(sysDict);
        return b;
    }

    @Override
    public ResultUtil<T> checkDictField(SysDict dict) {
        if (dict.getCode() != null) {
            int i = count(Wrappers.<SysDict>lambdaQuery()
                    .eq(SysDict::getTypeId, dict.getTypeId()).eq(SysDict::getDisable, 0)
                    .ne(dict.getId() != null, SysDict::getId, dict.getId()).eq(SysDict::getCode, dict.getCode()));
            if (i > 0) {
                return ResultUtil.build(ResultUtilCodeEnum.SYSDIC_CODE);
            }
        }
        if (StrUtil.isNotBlank(dict.getName())) {
            int i = count(Wrappers.<SysDict>lambdaQuery()
                    .eq(SysDict::getTypeId, dict.getTypeId()).eq(SysDict::getDisable, 0)
                    .ne(dict.getId() != null, SysDict::getId, dict.getId()).eq(SysDict::getName, dict.getName()));
            if (i > 0) {
                return ResultUtil.build(ResultUtilCodeEnum.SYSDIC_NAME);
            }
        }
        return ResultUtil.ok();
    }

    @Override
    public boolean deleteDict(Long id) {
        return update(Wrappers.<SysDict>lambdaUpdate()
                .eq(SysDict::getId, id)
                .set(SysDict::getDisable, 1));
    }

    @Override
    public List<SysDictVo> getSysDictVoJson(Page<SysDictVo> page, SysDictVo vo) {
        IPage<SysDictVo> sysDictVoIPage = baseMapper.getSysDictVoJson(page, vo);
        return sysDictVoIPage.getRecords();
    }

    @Override
    public String getWorkShipTitle() {
        List<SysDictVo> list = baseMapper.getDictByCode("workShift");
        LocalDateTime now = LocalDateTime.now().plusMinutes(30);
        for (SysDictVo vo : list) {
            String[] split = vo.getDescription().split("-");
            String[] t0 = split[0].split(":");
            LocalDateTime start = LocalDateTime.of(LocalDate.now(), LocalTime.of(Integer.parseInt(t0[0]), Integer.parseInt(t0[1]), 0));
            String[] t1 = split[1].split(":");
            LocalDateTime end = LocalDateTime.of(LocalDate.now(), LocalTime.of(Integer.parseInt(t1[0]), Integer.parseInt(t1[1]), 0));
            if (end.isBefore(start)) {
                end = end.plusDays(1);

            }
            if (now.isAfter(start) && now.isBefore(end)) {
                return vo.getName();
            }
        }
        return "白班";
    }

    @Override
    public SystemInfoVo getSystemInfo() {
        SystemInfoVo vo = new SystemInfoVo();
        List<SysDictVo> list = baseMapper.getDictByCode("systemInfo");
        for (SysDictVo sysDictVo : list) {
            switch (sysDictVo.getCode()) {
                case "1":
                    vo.setName(sysDictVo.getDescription());
                    break;
                case "2":
                    vo.setCity(sysDictVo.getDescription());
                    break;
                default:
                    break;
            }
        }
        return vo;
    }

    @Override
    public Long getTimeDiff(Integer code) {
        Long timeDiff = 0L;
        SysDictVo sysDictVo = new SysDictVo();
        sysDictVo.setSysDictTypeCode(TimeDiff.TIME.getName());
        sysDictVo.setCode(String.valueOf(code));
        List<SysDictVo> list = baseMapper.getDictCode(sysDictVo);
        if (list.isEmpty() || list.size() > 1) {
            return timeDiff;
        }
        SysDictVo diff = list.get(0);
        String s = diff.getDescription().replaceAll(" ", "");
        if (!NumberUtil.isInteger(s)) {
            return timeDiff;
        }
        timeDiff = Long.parseLong(s);
        if(timeDiff.equals(0L)){
            return timeDiff;
        }
        LocalDateTime now = LocalDateTime.now();
        //当天
        LocalDateTime nowDay = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        if(code.equals(TimeDiff.DAY.getCode())){
            //判断当日查询时间
            LocalDateTime queryTime = nowDay.plusMinutes(timeDiff);
            //8点之前显示昨天数据，8点之后显示当天数据
            if(now.isBefore(queryTime)){
                queryTime = queryTime.minusDays(1);
                Duration duration = Duration.between(nowDay, queryTime);
                timeDiff = duration.toMinutes();
            }
        } else if(code.equals(TimeDiff.WEEK.getCode())){
            LocalDateTime nowWeek = nowDay;
            if(nowDay.getDayOfWeek().compareTo(DayOfWeek.MONDAY) != 0){
                nowWeek = nowDay.with(TemporalAdjusters.previous(DayOfWeek.MONDAY));
            }
            //当周
            timeDiff = (timeDiff - 1) * 24 * 60;
            //周二之前显示上周数据 timeDiff-天数*24*60，周二之后显示当月数据 timeDiff
            LocalDateTime queryTime = nowWeek.plusMinutes(timeDiff);
            //一周有多少分钟
            Long weekMinutes = 7*24*60L;
            if(now.isBefore(queryTime)){
                timeDiff = timeDiff - weekMinutes;
            }
        } else if(code.equals(TimeDiff.MONTH.getCode())){
            //当月 精准到分钟
            LocalDateTime nowMonth = nowDay.with(TemporalAdjusters.firstDayOfMonth());
            //判断当月查询时间
            LocalDateTime queryTime = nowMonth.plusMinutes(timeDiff);
            //18号显示上月数据，18后显示当月数据
            if(now.isBefore(queryTime)){
                queryTime = queryTime.minusMonths(1);
                Duration duration = Duration.between(nowMonth, queryTime);
                timeDiff = duration.toMinutes();
            }
        } else if(code.equals(TimeDiff.YEAR.getCode())){
            //当年
            LocalDateTime nowYear = nowDay.with(TemporalAdjusters.firstDayOfYear());
            //判断当年查询时间
            LocalDateTime queryTime = nowYear.plusMinutes(timeDiff);
            //18号显示上月数据，18后显示当月数据
            if(now.isBefore(queryTime)){
                queryTime = queryTime.minusYears(1);
                Duration duration = Duration.between(nowYear, queryTime);
                timeDiff = duration.toMinutes();
            }
        }
        return timeDiff;
    }

    @Override
    public List<SysDictVo> getDictJsonList(SysDictVo vo) {
        List<SysDictVo> list = baseMapper.getSysDictVoJson(vo);
        return list;
    }

    @Override
    public List<SysDictVo> getChargeElement(String code) {
        return baseMapper.getDictByCode(code);
    }

    @Override
    public List<SysDictVo> getMsgTypeList(SysDictVo vo) {
        return baseMapper.getMsgTypeList(vo);
    }
}
